﻿using System;
using System.Data;
using System.Text;

namespace UnitTestHelper
{
    public class TestDataRecord : IDataRecord
    {
        private TestDataRecord()
        {}

        public static TestDataRecord FromDataRow(DataRow dataRow)
        {
            return new TestDataRecord {_dataRow = dataRow};
        }

        private DataRow _dataRow;

        public DataTable DataTable
        {
            get { return _dataRow.Table; }
        }

        public string GetName(int i)
        {
            return DataTable.Columns[i].ColumnName;
        }

        public string GetDataTypeName(int i)
        {
            return DataTable.Columns[i].DataType.Name;
        }

        public Type GetFieldType(int i)
        {
            return DataTable.Columns[i].DataType;
        }

        public object GetValue(int i)
        {
            return _dataRow[i];
        }

        public int GetValues(object[] values)
        {
            _dataRow.ItemArray.CopyTo(values, 0);
            return _dataRow.ItemArray.Length;
        }

        public int GetOrdinal(string name)
        {
            return DataTable.Columns[name].Ordinal;
        }

        public bool GetBoolean(int i)
        {
            return (bool) _dataRow[i];
        }

        public byte GetByte(int i)
        {
            return (byte) _dataRow[i];
        }

        public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
        {
            if (_dataRow[i].GetType() != typeof(string))
                throw new InvalidCastException(string.Format("Invalid attempt to GetBytes on column '{0}'.  The GetBytes function can only be used on columns of type String.", GetName(i)));

            return Encoding.ASCII.GetBytes(_dataRow[i].ToString(), (int) fieldOffset, length, buffer, bufferoffset);
        }

        public char GetChar(int i)
        {
            return (char) _dataRow[i];
        }

        public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
        {
            if (_dataRow[i].GetType() != typeof(string))
                throw new InvalidCastException(string.Format("Invalid attempt to GetBytes on column '{0}'.  The GetBytes function can only be used on columns of type String.", GetName(i)));

            return Encoding.ASCII.GetChars(Encoding.ASCII.GetBytes(_dataRow[i].ToString()), (int) fieldoffset, length, buffer, bufferoffset);
        }

        public Guid GetGuid(int i)
        {
            return (Guid) _dataRow[i];
        }

        public short GetInt16(int i)
        {
            return (short) _dataRow[i];
        }

        public int GetInt32(int i)
        {
            return (int) _dataRow[i];
        }

        public long GetInt64(int i)
        {
            return (long) _dataRow[i];
        }

        public float GetFloat(int i)
        {
            return (float) _dataRow[i];
        }

        public double GetDouble(int i)
        {
            return (double) _dataRow[i];
        }

        public string GetString(int i)
        {
            return (string) _dataRow[i];
        }

        public decimal GetDecimal(int i)
        {
            return (decimal) _dataRow[i];
        }

        public DateTime GetDateTime(int i)
        {
            return (DateTime) _dataRow[i];
        }

        public IDataReader GetData(int i)
        {
            throw new NotImplementedException();
        }

        public bool IsDBNull(int i)
        {
            return _dataRow[i] == null;
        }

        public int FieldCount
        {
            get { return _dataRow.ItemArray.Length; }
        }

        object IDataRecord.this[int i]
        {
            get { return _dataRow[i]; }
        }

        object IDataRecord.this[string name]
        {
            get { return _dataRow[name]; }
        }
    }
}